import { ArmatureController } from "./ArmatureController";
import { BoneController } from "./BoneController";
import { ItransformableItem } from "./ITransformableItem";

export class SelectedItemManager {
    public selectedItems = new Map<number, Set<ItransformableItem>>();
    public selectedItemsSet = new Set<ItransformableItem>();

    private _ctrl: ArmatureController;

    public constructor(ctrl: ArmatureController) {
        this._ctrl = ctrl;
    }

    public addSelectItem(selectItem: ItransformableItem): void {
        const key = selectItem.level;
        selectItem.selected(true);
        selectItem.notifyUI();
        this._ctrl.model.selectBone(selectItem.name);

        let sameLevelBones = this.selectedItems.get(key);
        if (sameLevelBones) {
            sameLevelBones.add(selectItem);
        } else {
            sameLevelBones = new Set<ItransformableItem>();
            sameLevelBones.add(selectItem);
            this.selectedItems.set(key, sameLevelBones);
        }

        this.selectedItemsSet.add(selectItem);
    }

    public removeSelectItem(testItem: ItransformableItem): void {
        for (let value of this.selectedItems.values()) {
            value.delete(testItem);
        }

        this.selectedItemsSet.delete(testItem);
    }

    public hadSelectItem(testItem: ItransformableItem): boolean {
        return this.selectedItemsSet.has(testItem);
    }

    public clearSelectedItems(): void {
        for (let value of this.selectedItems.values()) {
            for (const item of value) {
                item.selected(false);
            }
        }

        this.selectedItems.clear();
        this.selectedItemsSet.clear();
    }

    public getMinItems(): Set<ItransformableItem> | undefined {
        let minKey = Math.min(...this.selectedItems.keys());
        return this.selectedItems.get(minKey);
    }

    public getMaxItems(): Set<ItransformableItem> | undefined {
        let maxKey = Math.max(...this.selectedItems.keys());
        return this.selectedItems.get(maxKey);
    }

    public getOperateItem(): ItransformableItem | null {
        let bones = this.getMinItems();
        if (bones && bones.size > 0) {
            return Array.from(bones)[0];
        }

        return null;
    }

    public getFirstSelectedBone() {
        for (const item of this.selectedItemsSet) {
            if (item instanceof BoneController) {
                return item;
            }
        }

        return null;
    }
}